1. Field of the Invention
The present invention relates to the field of reference resolution for compiled program code and more particularly to resolving references in ahead-of-time (AOT) compiled program code.
2. Description of the Related Art
Software development has evolved over time from direct specification of a sequence of processor instructions, to the interpretation of high level source code into a sequence of processor instructions, to the compilation of high level source code into a sequence of processor instructions, to the compilation of high level source code into interpretable intermediate code able to be interpreted at run-time into a sequence of processor instructions. Initial software development focused on the delivery of functionality of code irrespective of the performance of the code at execution time. Over time, however, the complexity of software has compelled strong consideration of the performance implications of design choices in software development.
Just in time (JIT) compilation reflects one design choice in software development having an impact on program performance. In JIT compilation, source code is compiled into an intermediate format such as bytecode. The intermediate format, in turn, at the time of execution, is transformed into the machine instructions specific to the host computing platform. The performance enhancement resulting from JIT compilation originates from caching the results of translating blocks of code, and not simply evaluating each line or operand separately, or compiling the code at development time. Ahead of time (AOT) compilation differs from JIT compilation in that in AOT compilation, the transformation of the bytecode occurs prior to execution. AOT-oriented virtual machines enjoy execution time performance advantages over JIT-oriented virtual machines because the AOT-oriented virtual machine need not waste execution time processor cycles interpretation, profiling, and compiling intermediate bytecode so optimized programs run fast from start-up.
Irrespective of JIT or AOT compilation, the Java virtual machine (JVM) requires that all references to classes, instance fields, static fields, and methods within program code be resolved when each reference is first executed. In this regard, code generated for any reference that has not yet been resolved at compile time must cause the resolution to occur. Typically, resolution can be expensive and occurs when code is first executed. For code that is compiled AOT, almost all references must be unresolved because only the class of the method being compiled can be assumed to be resolved while the method is being compiled. Even references to super-classes within source code must be treated as unresolved during AOT compilation since the actual super-class loaded at runtime need not be the same class as when the code is AOT compiled nor even every time the JVM is invoked to execute the AOT compiled code.
While most applications do not have strict requirements for the time consumed when first executing a method, real-time applications have a high degree of sensitivity towards the delay experienced when first executing a method. Specifically, in a real-time environment, the first execution of a method or even one path inside a method must meet specified timing guarantees in order to operate correctly in the environment. Yet, in a virtual machine employing native code generated by an AOT compiler, forcing all applications to meet a deadline based upon the first execution time cost can be too restrictive since the first execution of a method is often much slower than subsequent executions because of the time required to resolve all class, field, and method references.
A virtual machine employing native code compiled by a compiler can avoid the first execution time cost as most references in a JIT environment are resolved prior to first execution of the JIT compiled code due to the repeated interpretation of the code prior to compilation. Still, real-time applications do not generally prefer to have a JIT compiler active since a run-time compiler can introduce too much non-determinism into the execution behavior of the application. Consequently, it is preferred to employ AOT generated code, in which almost all class, instance field, static field, and method references are treated as unresolved though the first execution time penalty for all resolutions can be prohibitive.